package game;

import java.awt.Color;
import javax.swing.JOptionPane;
import boundaryToMatador.GUI;

public class Game {

	// Variables
	private Player[] 	players;
	private Player		activePlayer;
	private int			numOfPlayers = 0;

	// Constructor
	public Game(int numPlayers) {

		// If numPlayers parameter is not between 2 and 6, popup.
		Object[] choices = {"2", "3", "4", "5", "6"};
		while ((numOfPlayers < 2) || (numOfPlayers > 6))
		{
			String sid = (String) JOptionPane.showInputDialog(
					null,
					"Vælg ønsket antal spillere",
					"Antal spillere ...",
					JOptionPane.PLAIN_MESSAGE,
					null,
					choices,
					choices[0]);

			if (sid != null)
			{
				numOfPlayers = Integer.parseInt(sid);
			}
		}

		// Creates array of players
		players = new Player[numOfPlayers];
		
		for (int i=0; i < numOfPlayers ; i++) {
			players[i] = new Player("Spiller " + (i+1));
		
		}

		// Set the active player to be the first player in the array.
		activePlayer = players[0];
		
	}

	public static void main(String[] args) {
		Game thisGame = new Game(0);
		thisGame.createGui();
		thisGame.playTurn();
	}

	//en metode der viser den aktive spillers muligheder for handel med bygninger
	//Frembringer et pop up vindue med op til fire valg muligheder
	private void showTradeOptions()
	{

		Object[]	possibleChoices;
		boolean	isSellPropertyPossible = false;
		boolean	isMortgagePossible = false;	

		
		boolean fullGrounds = false;


		int tradeOption = -1;
		while (tradeOption != 0)
		{
			String choices = "Spil tur";
			//checker om der findes grupper som den aktive spiller ejer, som der kan købes huse på
			if(Board.availableGroups(activePlayer).length != 0){
				int groupCheck;
				
					for (int i = 0; i < Board.availableGroups(activePlayer).length; i++) {
						int properties = 0;
						groupCheck =Board.availableGroups(activePlayer)[i]+1;
						for (int j = 0; j < Board.fields.length; j++) {
							if((Board.fields[j] instanceof Street) && (((Street)Board.fields[j]).getGroup() == groupCheck)){
								properties = properties + ((Street)Board.fields[j]).getProperty();
							}
							if(((groupCheck == 1)||(groupCheck == 8))&&(properties==10)){
								fullGrounds=true;
							}
							else if (properties ==15) {
								fullGrounds=true;
							}
						}
						if (fullGrounds==false) {
							choices = choices +",Køb huse";
						}
					}
				}

				//Checker om der findes hus på den aktive spillers grunde, som der kan sælges
				for (int i = 0; i < Board.availableGroups(activePlayer).length; i++) {
					for (int j = 0; j < Board.fields.length; j++) {
						if (Board.fields[j] instanceof Street){
							if((((Street) Board.fields[j]).getGroup()==Board.availableGroups(activePlayer)[i]+1)&&(((Street) Board.fields[j]).getProperty()!=0)){

								isSellPropertyPossible=true;

							}
						}
					}

				}

				if (isSellPropertyPossible==true) {
					choices= choices +",Sælg huse";
				}

				//checker om den aktive spiller ejer grunde, som enten kan pantsættes eller købes tilbage
				for (int i = 0; i < Board.fields.length; i++) {
					if(Board.fields[i]instanceof Ownable){
						if(((Ownable)Board.fields[i]).getOwner()==activePlayer){
							isMortgagePossible = true;
						}
					}

				}
				if(isMortgagePossible==true){
					choices = choices + ",Pansætning";
				}

				possibleChoices = choices.split(",");

				tradeOption = JOptionPane.showOptionDialog(null, activePlayer.getName() + " det er din tur!\nHvad vil du gøre ?\n", activePlayer.getName(), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, possibleChoices, possibleChoices[0]);
				if (tradeOption == -1){

					int closeOption  = JOptionPane.showConfirmDialog(
							null,
							"Ønsker du at afslutte spillet?",
							"Afslut spillet ...",
							JOptionPane.YES_NO_OPTION);

					if(closeOption == 0){
						System.exit(0);
					}

				}
				else if (possibleChoices[tradeOption].equals("Køb huse"))
				{
					String buyChoices = "";
					//Hvis spilleren har valgt køb huse
					Object[] possibleHousePurchase;

					int totalPrice = 0;
					int maxProperty=0;

					//første del der finder et gruppe nummer
					for (int i = 0; i < Board.availableGroups(activePlayer).length; i++) {
						
						int group = Board.availableGroups(activePlayer)[i]+1;
						int propertyCount =0;
						int priceCount = 1;
						int housePrice =0;
						//Anden del der skal finde en maxProperty der kan sættes  på den givne gruppe
						if((group == 1)||(group == 8)){
							maxProperty = 10;
						}
						else{
							maxProperty = 15;
						}
						for (int j = 0; j < Board.fields.length; j++) {
							if((Board.fields[j]instanceof Street)&&(((Street)Board.fields[j]).getGroup()==group)&&(((Street)Board.fields[j]).getMortgage()==false)){
								propertyCount= propertyCount + ((Street)Board.fields[j]).getProperty();
								housePrice=((Street)Board.fields[j]).getPropertyPrice();
							}
						}

						maxProperty= maxProperty-propertyCount;
						priceCount=0;
						totalPrice = 0;

						maxProperty= (Math.min(activePlayer.getAccount().getPoint()/housePrice, maxProperty));

						for (int k = 0; k < maxProperty; k++) {
							buyChoices = buyChoices + ",Gruppe " + group + " " + (k+1) + " huse";
						}
					}


					if(buyChoices == ""){
						
					}
					else
					{
						buyChoices = buyChoices.substring(1);
						Object[] possibeHousePurchases= buyChoices.split(",");

						String s = (String)JOptionPane.showInputDialog(
								null,
								"Vælge hvilken gruppe, og hvor mange grunde du ønsker",
								"Køb Ejendom Menu",
								JOptionPane.PLAIN_MESSAGE,
								null,
								possibeHousePurchases,
								possibeHousePurchases[0]);

						if ((s!= "")&& (s != null)) {
							String isolateFirstInt = s.substring(7,8);
							String isolateSecondInt = s.substring(9,s.indexOf(" " ,9));

							int GroupSelected = Integer.parseInt(isolateFirstInt);
							int HouseSelected = Integer.parseInt(isolateSecondInt);
							

							Board.buyPropertyGroup(activePlayer, GroupSelected, HouseSelected);					
						}

					}
				}
				else if (possibleChoices[tradeOption].equals("Sælg huse"))
				{
					String sellChoices = "";
					Object[] possibleHouseSells;
					int group =0;

					for (int i = 0; i < Board.availableGroups(activePlayer).length; i++) {
						int groupProperty=0;
						group= Board.availableGroups(activePlayer )[i]+1;
						for (int j = 0; j < Board.fields.length; j++) {
							if((Board.fields[j] instanceof Street)&&(group==((Street) Board.fields[j]).getGroup())){
								groupProperty= groupProperty + ((Street)Board.fields[j]).getProperty();
							}	
						}
						for (int j = 0; j < groupProperty; j++) {
							sellChoices = sellChoices + ",Gruppe " + group + " " + (j+1) + " hus(e)";
						}

					}
					if (sellChoices == ""){
						// Der sker ingen ting
					}
					else{
						sellChoices=sellChoices.substring(1);

						Object[] possibeHouseSell= sellChoices.split(",");

						String s = (String)JOptionPane.showInputDialog(
								null,
								"Vælge hvilken gruppe, og hvor mange grunde du ønsker at sælge",
								"Sælg Ejendom Menu",
								JOptionPane.PLAIN_MESSAGE,
								null,
								possibeHouseSell,
								possibeHouseSell[0]);

						if ((s != "") && (s != null)) {
							String isolateFirstInt = s.substring(7,8);
							
							String isolateSecondInt = s.substring(9,s.indexOf(" " ,9));

							int GroupSelected = Integer.parseInt(isolateFirstInt);
							int HouseSelected = Integer.parseInt(isolateSecondInt);

							Board.sellPropertyGroup(activePlayer, GroupSelected, HouseSelected);

						}

					}
				}
				else if (possibleChoices[tradeOption].equals("Pansætning"))
				{
					// Først skal der findes hvilke grupper der ejes
					// Denne skal skrives i en string med , foran
					// Så skal der findes hvilke grunde der er pantsat. her skrives det ind i Stringen uden ,
					String fieldMortgage= "";
					for (int i = 0; i < Board.fields.length; i++) {
						if((Board.fields[i]instanceof Ownable)&&(((Ownable)Board.fields[i]).getOwner()==activePlayer)){

							fieldMortgage= fieldMortgage + "," + (i+1) + " " + ((Ownable)Board.fields[i]).getName();
							if((((Ownable)Board.fields[i]).getMortgage()==true)){
								fieldMortgage = fieldMortgage + " *** Pantsat ***";
							}
						}

					}
					if(fieldMortgage == ""){
						
					}

					else{
						fieldMortgage=fieldMortgage.substring(1);

						Object[] possibeHousePurchases= fieldMortgage.split(",");

						String s =	(String)JOptionPane.showInputDialog(
								null,
								"Vælge hvilken gruppe, og hvor mange grunde du ønsker",
								"Køb Ejendom Menu",
								JOptionPane.PLAIN_MESSAGE,
								null,
								possibeHousePurchases,
								possibeHousePurchases[0]);

						if((s != "") && (s != null)){
							String isolateFirstInt = s.substring(0,s.indexOf(" " ,0));

							int fieldSelected = Integer.parseInt(isolateFirstInt)-1;

							((Ownable)Board.fields[fieldSelected]).changeMortgage();

						}
					}

				}
				GUI.setBalance(activePlayer.getName(), activePlayer.getAccount().getPoint());
			}

		}

		public void playTurn() {

			if (activePlayer.getTurnsInJail() == 0)	
			{
				showTradeOptions();
				DiceCup.rollDice();
				activePlayer.movePlayer(DiceCup.getSum());
				updateGui(DiceCup.getDie1(), DiceCup.getDie2());

				Board.fields[activePlayer.getPosition()-1].landOnField(activePlayer);
				

				for (int i = 0; i < numOfPlayers; i++)
				{
					GUI.setBalance(players[i].getName(), players[i].getAccount().getPoint());
				}
			} 
			else 
			{ //Hvis spilleren er kommet i fængsel
				((GoToJail) Board.fields[30]).isInJail(activePlayer);
				
			}

			if (checkVictoryCondition()) 
			{
				presentResult(activePlayer);
				resetGame();
				playTurn();
			} 
			else 
			{
				passTurn();
				playTurn();
			}

		}	

		public void passTurn() {

			Player playingNow = activePlayer;


			for (int i=0; i < numOfPlayers; i++)
			{
				if (!players[i].getGameOver())
				{
					if (playingNow == players[i])
					{
						if (i == numOfPlayers-1)
						{
							activePlayer = players[0];
						}
						else
						{
							activePlayer = players[i+1];
						}
					}
				}
			}

		}

		public void presentResult(Player player) {
			GUI.showMessage(player.getName() + " har vundet spillet!");
		}

		public void resetGame() {
			for (int i = 0; i < Board.fields.length; i++)
			{
				if (Board.fields[i] instanceof Ownable)
				{
					((Ownable) Board.fields[i]).setOwner(null);
					if (Board.fields[i] instanceof Street)
					{
						while (((Street) Board.fields[i]).getProperty() > 0)
						{
							((Street) Board.fields[i]).sellProperty(1);
						}
					}
				}
			}
			
			for (int i =0 ; i < numOfPlayers; i++){
				
				players[i].getAccount().resetPoints();

				GUI.removeAllCars(players[i].getName());
				GUI.setCar(players[i].getPosition(), players[i].getName());
				GUI.setBalance(players[i].getName(), players[i].getAccount().getPoint());
			}
			
		}
		
		// checker for om der er 1 spiller tilbage, og finder en vinder.
		public boolean checkVictoryCondition() {
			boolean playersLeft = false;
			for (int i=0 ; i < numOfPlayers; i++) {

				if ((players[i].getAccount().getPoint() > 0) && (players[i] != activePlayer))
				{
					playersLeft = true;	
				}

			}

			return !playersLeft;
		}

		public void updateGui(int die1, int die2)
		{
			GUI.setDice(die1, die2);
			for (int i=0; i < numOfPlayers; i++)
			{
				GUI.removeAllCars(players[i].getName());
				GUI.setCar(players[i].getPosition(), players[i].getName());
				GUI.setBalance(players[i].getName(), players[i].getAccount().getPoint());
			}
		}

		public void createGui()
		{
			Color[] color = new Color[] {
					Color.BLACK,
					Color.BLUE,
					Color.GREEN,
					Color.RED,
					Color.YELLOW,
					Color.WHITE
			};

			GUI.create("fields.txt");
			for (int i = 0; i < numOfPlayers; i++)
			{
				GUI.addPlayer(players[i].getName(), players[i].getAccount().getPoint(), color[i]);
			}
		}
	}